package com.google.code.ptrends.catparsers;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang.StringUtils;

import com.google.code.ptrends.catparsers.utils.RegexHelper;
import com.google.code.ptrends.common.entities.Category;
import com.google.code.ptrends.common.entities.Property;
import com.google.code.ptrends.common.entities.Session;
import com.google.code.ptrends.entities.ETLItem;
import com.google.code.ptrends.entities.ParametersStrings;
import com.google.code.ptrends.excel.ExcelReader;
import com.google.code.ptrends.excel.entities.Worksheet;

public class ControllerCategoryParser extends AbstractCategoryParser {

	private final List<Matcher> matchers;

	public ControllerCategoryParser(final ExcelReader reader,
			final Worksheet worksheet, final Session session) {
		super(reader, worksheet, session);
		matchers = new ArrayList<Matcher>();
		matchers.add(Pattern.compile(RegexHelper.getRegex("controller00"))
				.matcher(""));
		matchers.add(Pattern.compile(RegexHelper.getRegex("controller10"))
				.matcher(""));
		matchers.add(Pattern.compile(RegexHelper.getRegex("controller20"))
				.matcher(""));
		matchers.add(Pattern.compile(RegexHelper.getRegex("controller30"))
				.matcher(""));
		matchers.add(Pattern.compile(RegexHelper.getRegex("controller40"))
				.matcher(""));
		matchers.add(Pattern.compile(RegexHelper.getRegex("controller50"))
				.matcher(""));
		matchers.add(Pattern.compile(RegexHelper.getRegex("controller60"))
				.matcher(""));
	}

	@Override
	protected ETLItem createItem(final String description, final String priceUSD) {
		ETLItem item = null;
		String manufacturer;
		String model;
		List<Property> props;
		if (!(StringUtils.isNotBlank(description) && StringUtils
				.isNotBlank(priceUSD)))
			return null;
		props = new ArrayList<Property>();
		for (Matcher matcher : matchers) {
			matcher.reset(description);
			if (matcher.find()) {
				switch (matchers.indexOf(matcher)) {
				case 0: // Adapters
					manufacturer = matcher.group(2);
					model = matcher.group(3);
					props.add(buildProperty(ParametersStrings.CONTROLLER,
							matcher.group(1)));
					break;
				case 1: // Batteries
					manufacturer = matcher.group(1);
					model = matcher.group(2);
					props.add(buildProperty(ParametersStrings.CAPACITY,
							matcher.group(3)));
					break;
				case 2: // Activation keys
					manufacturer = matcher.group(1);
					model = matcher.group(2);
					// props = null;
					break;
				case 3: // Controllers
				case 4: // Modems
					manufacturer = matcher.group(2);
					model = matcher.group(3);
					props.add(buildProperty(ParametersStrings.CONTROLLER,
							matcher.group(1)));
					if (StringUtils.isNotBlank(matcher.group(4)))
						props.add(buildProperty(ParametersStrings.INTERFACE,
								matcher.group(4)));
					break;
				case 5: // Adapters
					manufacturer = matcher.group(3);
					model = matcher.group(4);
					props.add(buildProperty(ParametersStrings.INTERFACE_FROM,
							matcher.group(1)));
					props.add(buildProperty(ParametersStrings.INTERFACE_TO,
							matcher.group(2)));
					if (StringUtils.isNotBlank(matcher.group(5)))
						props.add(buildProperty(ParametersStrings.INTERFACE,
								matcher.group(5)));
					props.add(buildProperty(ParametersStrings.JACK,
							matcher.group(6)));
					break;
				case 6: // Splitters
					manufacturer = matcher.group(3);
					model = matcher.group(4);
					props.add(buildProperty(ParametersStrings.CONTROLLER,
							matcher.group(1)));
					props.add(buildProperty(ParametersStrings.OUTPUT_COUNT,
							matcher.group(2)));
					props.add(buildProperty(ParametersStrings.POWER_SUPPLY,
							matcher.group(5)));
					break;
				default:
					throw new NotImplementedException("Unreachable code");
				}
				item = buildItem(Category.CONTROLLER, manufacturer, model,
						new Float(priceUSD), new Date());
				item.setParameters(props);
			}
		}
		return item;
	}
}
